/************************************************************************

								Heroes IV
					  Copyright 2001, The 3DO Company

	------------------------------------------------------------------
  						 abstract_combat_ai_spell_action.cpp

	$Header: $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "abstract_combat_ai_spell_action.h"

#include "battlefield.h"
#include "can_cast.h"
#include "combat_ai.h"
#include "combat_creature.h"
#include "combat_spell.h"
#include "combat_spell_registration.h"
#include "spell.h"
#include "spell_list.h"

void t_combat_ai_spell_action::perform_action()
{
	m_battlefield.set_spell( m_spell );

	m_spell->ai_cast_spell();
}

void t_combat_ai_spell_action::weigh_action( t_combat_ai const& owner )
{
}

// get value of cancelling a list of spells
double get_cancel_value( t_battlefield& battlefield, t_combat_creature const& target, 
						 t_spell_list const& spells )
{
	t_spell_list::const_iterator	index = spells.begin();
	t_spell_list::const_iterator	end = spells.end();
	t_combat_spell_ptr				spell_object;
	double							result = 0.0;
	t_combat_creature*				acting_creature = battlefield.get_acting_creature();

	for (; index != end; ++index)
	{
		spell_object = create_combat_spell( battlefield, *index );
		assert( spell_object != 0 );
		if (spell_object == 0)
			continue;
		spell_object->set_caster( acting_creature );
		result += spell_object->get_cancel_weight( target );
	}
	return result;
}

// -----------------------------------------------------------------
// get weight of damage spell
// -----------------------------------------------------------------
double get_damage_spell_weight( t_combat_creature const& caster,
							    t_combat_creature const& target,
								t_spell					 spell )
{
	int				power = caster.get_spell_power(spell);
	int				damage = target.modify_spell_damage( &caster, power, spell );
	t_battlefield&	battlefield = caster.get_battlefield();

	if (!spellcasting_is_worthwhile( battlefield, caster.get_controller() ))
		return 0.0;
	if (damage > target.get_total_hits())
		damage = target.get_total_hits();

	double weight = target.get_ai_value( damage );

	weight += t_combat_ai::get_zoc_change_weight(damage, target, false, 0);
	if (target.belongs_to_defender() == caster.get_controller())
		weight = -weight;
	if (target.has_magic_mirror() && can_affect( target, spell, caster ))
	{
		damage = caster.modify_spell_damage( &caster, power / 2, spell );
		if (damage > caster.get_total_hits())
			damage = caster.get_total_hits();
		weight -= caster.get_ai_value( damage );
		weight -= t_combat_ai::get_zoc_change_weight( damage, caster, false, 0 );
	}
	return weight;
}
